﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ScaffoldIt.Configuration;
using Microsoft.VisualStudio.TextTemplating;

namespace ScaffoldIt
{
    static class ParametersHelpers
    {
        public static void Apply(this TextTemplatingSession session, IEnumerable<Parameter> parameters)
        {
            if (parameters == null) 
                return;

            foreach (var parameter in parameters)
            {
                session[parameter.Code] = parameter.GetValue();
            }    
        }

        public static IEnumerable<Parameter> GetParameters(this IEnumerable<Template> templates, ScaffoldingContext ctx)
        {
            var globals = ctx.Config.Parameters.Where(p => p.IsGlobal);
            foreach (var parameter in globals)
            {
                yield return parameter;
            }
            
            var paramsGroup = templates.SelectMany(t => t.Parameters).GroupBy(p => p.Code);

            foreach (var elt in paramsGroup)
            {
                var root = elt.First();

                if (!root.ValidateCode())
                {
                    ctx.Output.WriteLine("ERROR : parameter code " + elt.Key + " is invalid, parameter code must be used as code variable (only letters and numbers)");
                    continue;
                }

                var returnParam = ctx.Config.Parameters.FirstOrDefault(p => p.Code == root.Code);

                if (returnParam == null) 
                    returnParam = root;

                if (!elt.All(p => p.Type == root.Type))
                {
                    ctx.Output.WriteLine("WARNING : parameter " + elt.Key + " is defined with different types");
                }
                
                var paramWithValue = elt.FirstOrDefault(p => !string.IsNullOrEmpty(p.Value));
                if (paramWithValue != null)
                {
                    returnParam.Value = paramWithValue.Value;                    
                }

                if (!returnParam.ValidateType())
                {
                    ctx.Output.WriteLine("WARNING : parameter type is invalid for parameter " + elt.Key + ", the parameter will be treated as string. Valid parameter types are " + Parameter.ParamTypesList());
                    continue;
                }

                yield return returnParam;
            }
        }
    }
}
